﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using IRC.IRepairClouds.DataLayer;

namespace IRC.IRepairClouds.WebClient
{
    public class AuthRequirements
    {
        public Dictionary<EPartnerRole.PartnerRoles, EUserRole.Role?> Roles { get; private set; }
        private static EUserRole.Role? BinOr(EUserRole.Role? r1, EUserRole.Role? r2)
        {
            if (r1 == null || r2 == null)
                return null;
            return r1 | r2;
        }

        private AuthRequirements()
        {
            Roles = new Dictionary<EPartnerRole.PartnerRoles, EUserRole.Role?>();
        }

        public AuthRequirements(AuthRequirements authRequirements)
        {
            Roles = new Dictionary<EPartnerRole.PartnerRoles, EUserRole.Role?>(authRequirements.Roles);
        }

        public AuthRequirements(EPartnerRole.PartnerRoles partnerRoles)
            : this()
        {
            DoOr(partnerRoles, null);
        }

        public AuthRequirements(EPartnerRole.PartnerRoles partnerRoles, EUserRole.Role userRoles)
            : this()
        {
            DoOr(partnerRoles, userRoles);
        }

        public AuthRequirements Or(EPartnerRole.PartnerRoles partnerRoles)
        {
            return DoOr(partnerRoles, null);
        }

        public AuthRequirements Or(EPartnerRole.PartnerRoles partnerRoles, EUserRole.Role userRoles)
        {
            return DoOr(partnerRoles, userRoles);
        }

        private AuthRequirements DoOr(EPartnerRole.PartnerRoles partnerRoles, EUserRole.Role? userRoles)
        {
            foreach (var pr in partnerRoles.Unflags())
            {
                EUserRole.Role? ur;
                if (Roles.TryGetValue(pr, out ur))
                    Roles[pr] = BinOr(ur, userRoles);
                else
                    Roles[pr] = userRoles;
            }
            return this;
        }

        public AuthRequirements Or(AuthRequirements requirements)
        {
            foreach (var i in requirements.Roles)
                this.DoOr(i.Key, i.Value);
            return this;
        }
    }
}